from rest_framework import serializers

from articles.models import Article, Comment
from users.models import User
from users.serializers import UserDetailModelSerializer
from django_redis import get_redis_connection
from django.forms.models import model_to_dict
import json

class ArticleCreateSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ['content', 'article_imgs', 'is_show', 'user']
        model = Article
        extra_kwargs = {
            'content': {'write_only': True, 'required': True},
            'user': {'write_only': True, 'required': True},
            'is_show': {'write_only': True, 'required': True},
            'article_imgs': {'write_only': True, 'required': False},
        }

    def validate(self, data):
        if not data.get('content'):
            raise serializers.ValidationError('内容不能为空')
        return data

    def create(self, validated_data):
        article = Article.objects.create(
            content=validated_data['content'],
            user=validated_data['user'],
            is_show=validated_data['is_show']
        )
        if validated_data['article_imgs']:
            article.article_imgs = validated_data['article_imgs']
            article.save()
        return article


class ArticleListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['id', 'content', 'article_imgs', 'is_show', 'create_time', 'add_love', 'add_collect']


class ArticleUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ['is_show']
        model = Article
        extra_kwargs = {
            'is_show': {'write_only': True, 'required': True},
        }

    def update(self, instance, validated_data):
        instance.is_show = int(validated_data.get('is_show', False))
        instance.save()
        return instance


class AllArticleSerializer(serializers.ModelSerializer):
    user = UserDetailModelSerializer()
    comments = serializers.SerializerMethodField(source='get_comments')
    create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')

    def get_comments(self, obj):
        return obj.comment_list.all().count()

    class Meta:
        model = Article
        fields = ['id', 'content', 'article_imgs', 'is_show',
                  'user', 'add_love', 'comments', 'add_collect', 'create_time']


class ArticleUpdateSomeSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ['add_love', 'add_collect', 'user']
        model = Article
        extra_kwargs = {
            'add_love': {'write_only': True, 'required': False},
            'add_collect': {'write_only': True, 'required': False},
            'user': {'write_only': True, 'required': False},
        }

    def update(self, instance, validated_data):
        redis = get_redis_connection('love_collect')
        user_id = validated_data['user'].id
        article_id = instance.id
        redis_add_love = redis.hget(f'{user_id}_{article_id}', 'add_love')
        redis_cancel_love = redis.hget(f'{user_id}_{article_id}', 'cancel_love')
        redis_add_collect = redis.hget(f'{user_id}_{article_id}', 'add_collect')
        redis_cancel_collect = redis.hget(f'{user_id}_{article_id}', 'cancel_collect')
        # 判断之前是否点赞过，在判断是否再次点赞
        if redis_add_love == b'1' and validated_data.get('add_love') == 1:
            # 取消点赞
            instance.add_love = -1 + instance.add_love
            instance.save()
            # 设置取消点赞，并删除已经点赞
            redis.hdel(f'{user_id}_{article_id}', 'add_love')
            redis.hset(f'{user_id}_{article_id}', 'cancel_love', -1)
            raise serializers.ValidationError(detail={'add_love': -1, 'error': '已经点赞过了，现在取消点赞', 'id': 0})

        # 判断之前是否取消点赞，在判断是否再次取消点赞
        if redis_cancel_love == b'-1' and validated_data.get('add_love') == -1:
            instance.add_love = 1 + instance.add_love
            instance.save()
            # 设置点赞，并删除取消点赞
            redis.hdel(f'{user_id}_{article_id}', 'cancel_love')
            redis.hset(f'{user_id}_{article_id}', 'add_love', 1)
            raise serializers.ValidationError(
                detail={'add_love': 1, 'error': '已经取消点赞过了，现在点赞', 'id': article_id})

        # 判断之前是否收藏过，在判断是否再次收藏
        if redis_add_collect == b'1' and validated_data.get('add_collect') == 1:
            # 取消收藏
            instance.add_collect = -1 + instance.add_collect
            instance.save()
            # 设置取消收藏，并删除已经收藏
            redis.hdel(f'{user_id}_{article_id}', 'add_collect')
            redis.hset(f'{user_id}_{article_id}', 'cancel_collect', -1)
            raise serializers.ValidationError(detail={'add_collect': -1, 'error': '已经收藏过了，现在取消收藏', 'id': 0})

        # 之前是取消收藏过，但是现在you取消收藏
        if redis_cancel_collect == b'-1' and validated_data.get('add_collect') == -1:
            # 收藏
            instance.add_collect = 1 + instance.add_collect
            instance.save()
            # 设置收藏，并删除取消收藏
            redis.hdel(f'{user_id}_{article_id}', 'cancel_collect')
            redis.hset(f'{user_id}_{article_id}', 'add_collect', 1)
            raise serializers.ValidationError(
                detail={'add_collect': 1, 'error': '已经取消收藏过了，现在收藏', 'id': article_id})

        pipeline = redis.pipeline()
        pipeline.multi()
        if validated_data.get('add_love') == 1:
            # 把之前redis取消点赞删除
            redis.hdel(f'{user_id}_{article_id}', 'cancel_love')
            pipeline.hset(f'{user_id}_{article_id}', 'add_love', 1)
        if validated_data.get('add_love') == -1:
            # 把之前redis点赞删除
            redis.hdel(f'{user_id}_{article_id}', 'add_love')
            pipeline.hset(f'{user_id}_{article_id}', 'cancel_love', -1)
        if validated_data.get('add_collect') == 1:
            # 把之前redis取消收藏删除
            redis.hdel(f'{user_id}_{article_id}', 'cancel_collect')
            pipeline.hset(f'{user_id}_{article_id}', 'add_collect', 1)
        if validated_data.get('add_collect') == -1:
            # 把之前redis收藏删除
            redis.hdel(f'{user_id}_{article_id}', 'add_collect')
            pipeline.hset(f'{user_id}_{article_id}', 'cancel_collect', -1)
        pipeline.execute()

        # if validated_data.get('add_love')===1:
        instance.add_love = int(validated_data.get('add_love')) + instance.add_love if validated_data.get(
            'add_love') else instance.add_love
        instance.add_collect = int(validated_data.get('add_collect')) + instance.add_collect if validated_data.get(
            'add_collect') else instance.add_collect
        instance.save()
        return instance


class ArticleCommentSerializer(serializers.ModelSerializer):
    # create_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')
    # user = UserDetailModelSerializer()
    child_comment = serializers.SerializerMethodField(source='get_child_comment')

    def get_child_comment(self, obj):
        comments = Comment.objects.filter(article_id=obj.article_id, is_active=True, level=0).all()
        comment_list = []
        for comment in comments:
            parent_dict = model_to_dict(comment)
            parent_dict['user'] = UserDetailModelSerializer(instance=comment.user).data
            children = Comment.objects.filter(comment_id=comment.id, is_active=True, level=1).all()
            for child in children:
                child_dict = model_to_dict(child)
                child_dict['user'] = UserDetailModelSerializer(instance=child.user).data
                parent_dict['child_comment'] = child_dict
                # comment_list.append(child_dict)
        # comment_dict = model_to_dict(comment_list)
        # comment_json = comment_list

        return parent_dict

    class Meta:
        model = Comment
        fields = ['child_comment']
        # extra_kwargs = {
        #     'id': {'read_only': True},
        #     'create_time': {'read_only': True},
        #     'add_love': {'read_only': True},
        #     'content': {'read_only': True},
        # }


class AddCommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['content', 'user', 'article', 'comment', 'level']
        extra_kwargs = {
            'content': {'write_only': True, 'required': True},
            'comment': {'write_only': True, 'required': False},
            'level': {'allow_null': True},
        }

    def validate(self, data):
        if not data.get('content'):
            raise serializers.ValidationError('内容不能为空')
        return data

    def create(self, validated_data):
        user = validated_data['user']
        article = validated_data['article']
        content = validated_data['content']
        comment_id = validated_data.get('comment')    # 父级评论id
        level = validated_data.get('level')    # 评论层级
        if not comment_id:
            # 根评论
            comment = Comment.objects.create(
                content=content,
                user=user,
                article=article,
                level=0
            )
        else:
            # 子评论
            comment = Comment.objects.create(
                content=content,
                user=user,
                article=article,
                level=1,
                comment=comment_id
            )
        return comment


# 删除评论
class DeleteCommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['id']
